package com.joysuch.wwyt.api.base.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.zlg.common.enums.BusinessTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.joysuch.wwyt.alert.service.NoticeWaitingTriggerListService;
import com.joysuch.wwyt.api.base.dto.*;
import com.joysuch.wwyt.bp.bean.BpDeviceFacilityListBean;
import com.joysuch.wwyt.bp.bean.BpDeviceFacilityListSearchBean;
import com.joysuch.wwyt.bp.entity.contractor.BpContractor;
import com.joysuch.wwyt.bp.service.BpContractorService;
import com.joysuch.wwyt.bp.service.BpDepartService;
import com.joysuch.wwyt.bp.service.BpDeviceFacilityCollectionService;
import com.joysuch.wwyt.bp.service.BpJobService;
import com.joysuch.wwyt.common.entity.CommonBusinessNotice;
import com.joysuch.wwyt.common.enums.AppBusinessNoticeTypes;
import com.joysuch.wwyt.common.service.CommonBusinessNoticeService;
import com.joysuch.wwyt.core.bean.BaseDepartDutyUserBean;
import com.joysuch.wwyt.core.bean.BaseUserListBean;
import com.joysuch.wwyt.core.bean.BaseUserListWfSearchBean;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.entity.CascadeConfig;
import com.joysuch.wwyt.core.security.ShiroUser;
import com.joysuch.wwyt.core.service.BaseRoleDataAuthService;
import com.joysuch.wwyt.core.service.BaseRoleService;
import com.joysuch.wwyt.core.service.BaseUserService;
import com.joysuch.wwyt.core.service.CascadeConfigService;
import com.joysuch.wwyt.core.support.Context;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zero
 * @since 2022/2/15 14:48
 */
@Slf4j
@RestController
@RequestMapping("/api/base")
@Api(tags = "流程引擎的数据源接口")
public class BaseController {

    @Autowired
    private BaseUserService baseUserService;

    @Autowired
    private BpDepartService bpDepartService;

    @Autowired
    private BpJobService bpJobService;

    @Autowired
    private BaseRoleService baseRoleService;

    @Autowired
    private BaseRoleDataAuthService dataAuthService;

    @Autowired
    private BpContractorService bpContractorService;

    @Autowired
    private BpDeviceFacilityCollectionService bpDeviceFacilityCollectionService;

    @Autowired
    private CommonBusinessNoticeService commonBusinessNoticeService;

    @Autowired
    private NoticeWaitingTriggerListService noticeWaitingTriggerListService;

    @Autowired
    private CascadeConfigService cascadeConfigService;

    @GetMapping("/user/findList")
    @ApiOperation("全部人员信息接口")
    public ResultBean findUserList(String departId, String jobId, String roleId, String userId, Long tenantId, String orgCode) {
        //为兼容后期可能会有多个部门，岗位，角色搜索。多个时前端使用  ,  分割
        return ResultBean.success(baseUserService.findUserList(departId, jobId, roleId, userId, tenantId, orgCode));
    }

    @GetMapping("/user/findBeanList")
    @ApiOperation("全部人员信息接口")
    public ResultBean findBeanList(String userIdStr,String userNameStr, Long tenantId, String orgCode) {
        //为兼容后期可能会有多个部门，岗位，角色搜索。多个时前端使用  ,  分割
        return ResultBean.success(baseUserService.findBeanList(userIdStr, userNameStr, tenantId, orgCode));
    }

    @GetMapping("/user/findListByPage")
    @ApiOperation("全部人员信息分页接口")
    public ResultBean findUserListByPage(Integer page, Integer size, String departId, String jobId, String roleId,
                                         String userId, String name, String departName,String code,
                                         Long tenantId, String orgCode) {
        //为兼容后期可能会有多个部门，岗位，角色搜索。多个时前端使用  ,  分割
        return baseUserService.findUserListByPage(page, size, departId, jobId, roleId, userId,
                name, departName,code, tenantId, orgCode);
    }

    @GetMapping("/user/findDepartManagerByUserId")
    @ApiOperation("根据用户Id获取所在部门负责人信息")
    public ResultBean findDepartManagerByUserId(Long userId) {
        ApiUserDto apiUserDto = new ApiUserDto();
        BaseDepartDutyUserBean bean = baseUserService.getDepartDutyUser(userId);
        apiUserDto.setId(bean.getId());
        apiUserDto.setName(bean.getRealName());
        return ResultBean.success(apiUserDto);
    }

    @GetMapping("/user/findDepartLeaderByDepartId")
    @ApiOperation("根据部门Id获取所在部门负责人信息")
    public ResultBean findDepartLeaderByDepartId(Long departId,Integer level) {
        return ResultBean.success(baseUserService.getDepartDutyUserList(departId,level));
    }

    @GetMapping("/depart/findList")
    @ApiOperation("全部部门信息接口")
    public ResultBean findDepartList(String departName, String departCode, Long tenantId, String orgCode) {
        List<ApiDepartDto> departVoList = bpDepartService.getListForApi(departName, departCode, tenantId, orgCode);
        return ResultBean.success(departVoList);
    }

    @GetMapping("/depart/findListByChiefId")
    @ApiOperation("负责人全部部门信息接口")
    public ResultBean findListByChiefId(Long chiefId, Long tenantId, String orgCode) {
        List<ApiDepartDto> departVoList = bpDepartService.findListByChiefId(chiefId, tenantId, orgCode);
        return ResultBean.success(departVoList);
    }

    @GetMapping("/depart/findListByPage")
    @ApiOperation("全部部门信息分页接口")
    public ResultBean findDepartListByPage(Integer page, Integer size, String departName, String departCode, Long tenantId, String orgCode) {
        Page<ApiDepartDto> apiDepartVoPage = bpDepartService.getListByPageForApi(page, size, departName, departCode, tenantId, orgCode);
        if (CollectionUtil.isNotEmpty(apiDepartVoPage.getRecords())) {
            return ResultBean.pageData(apiDepartVoPage.getRecords(), apiDepartVoPage.getTotal());
        }
        return ResultBean.pageData(new ArrayList<>(), apiDepartVoPage.getTotal());
    }

    @GetMapping("/depart/findPerm")
    @ApiOperation("用户的部门权限")
    public ResultBean findDepartListByPage(Long userId, Long tenantId, String orgCode) {
        List<Long> departIds = dataAuthService.findDepartIdsByUserId(userId, tenantId, orgCode);
        return ResultBean.success(departIds);
    }

    @GetMapping("/job/findList")
    @ApiOperation("全部岗位信息接口")
    public ResultBean findJobList(String jobName, Long tenantId, String orgCode) {
        List<ApiJobDto> apiJobDtoList = bpJobService.getListForApi(jobName, tenantId, orgCode);
        return ResultBean.success(apiJobDtoList);
    }

    @GetMapping("/job/findListByPage")
    @ApiOperation("全部岗位信息分页接口")
    public ResultBean findJobListByPage(Integer page, Integer size, String jobName, Long tenantId, String orgCode) {
        Page<ApiJobDto> apiJobVoPage = bpJobService.getListByPageForApi(page, size, jobName, tenantId, orgCode);
        if (CollectionUtil.isNotEmpty(apiJobVoPage.getRecords())) {
            return ResultBean.pageData(apiJobVoPage.getRecords(), apiJobVoPage.getTotal());
        }
        return ResultBean.pageData(new ArrayList<>(), apiJobVoPage.getTotal());
    }

    @GetMapping("/role/findList")
    @ApiOperation("全部角色信息接口")
    public ResultBean findRoleList(String roleName, String remark, Long tenantId, String orgCode) {
        List<ApiRoleDto> apiRoleDtoList = baseRoleService.getListForApi(roleName, remark, tenantId, orgCode);
        return ResultBean.success(apiRoleDtoList);
    }

    @GetMapping("/role/findListByPage")
    @ApiOperation("全部角色信息分页接口")
    public ResultBean findRoleListByPage(Integer page, Integer size, String roleName, String remark, Long tenantId, String orgCode) {
        Page<ApiRoleDto> listByPageForApi = baseRoleService.getListByPageForApi(page, size, roleName, remark, tenantId, orgCode);
        if (CollectionUtil.isNotEmpty(listByPageForApi.getRecords())) {
            return ResultBean.pageData(listByPageForApi.getRecords(), listByPageForApi.getTotal());
        }
        return ResultBean.pageData(new ArrayList<>(), listByPageForApi.getTotal());
    }

    @RequestMapping("/user/findListBySysUserOrContractor")
    @ApiOperation("获取系统用户和承包商用户")
    public Object detailList(Integer page, Integer size, BaseUserListWfSearchBean condition) {
        org.springframework.data.domain.Page<BaseUserListBean> data = baseUserService.findDetailInfoByPageWf(QPageRequest.of(page, size), condition);
        return ResultBean.pageData(data.getContent(), data.getTotalElements());
    }

    @GetMapping("/device/page")
    @ApiOperation(value = "设备-分页查询", response = BpContractor.class)
    public ResultBean device(Integer page, Integer size, String codeName, String deviceTypeName) {
        BpDeviceFacilityListSearchBean bean = new BpDeviceFacilityListSearchBean();
        bean.setCodeName(codeName);
        bean.setDeviceTypeName(deviceTypeName);
        org.springframework.data.domain.Page<BpDeviceFacilityListBean> data = bpDeviceFacilityCollectionService.findByPage(PageRequest.of(page, size), bean);
        return ResultBean.pageData(data.getContent(), data.getTotalElements());
    }

    @GetMapping("/contractor/page")
    @ApiOperation(value = "承包商-分页查询", response = BpContractor.class)
    public ResultBean contractor(Integer page, Integer size, String companyName) {
        ResultBean pgRes = bpContractorService.page(PageRequest.of(page, size), "合格承包商", null, companyName);
        return ResultBean.pageData((List<BpContractor>) pgRes.getData(), pgRes.getLength());
    }

    @GetMapping("/departcontractor/page")
    @ApiOperation(value = "承包商-分页查询", response = BpContractor.class)
    public ResultBean page(Integer page, Integer size, String departName, String flag, Long tenantId, String orgCode) {
        if ("1".equals(flag)) {
            ResultBean res = bpContractorService.page(PageRequest.of(page, size), "合格承包商", null, departName);
            List<ApiDepartDto> cvtList = ((List<BpContractor>) res.getData()).stream().map(c -> {
                ApiDepartDto d = new ApiDepartDto();
                d.setId(c.getId());
                d.setDepartCode(c.getCode());
                d.setDepartName(c.getCompanyName());
                return d;
            }).collect(Collectors.toList());
            return ResultBean.pageData(cvtList, res.getLength());
        } else {
            Page<ApiDepartDto> apiDepartVoPage = bpDepartService.getListByPageForApi(page, size, departName, null, tenantId, orgCode);
            return ResultBean.pageData(apiDepartVoPage.getRecords(), apiDepartVoPage.getTotal());
        }
    }

    @PostMapping("/notify/send")
    public ResultBean sendNotice(@RequestBody ApiSendNotice req) {
        try {
            ShiroUser su = new ShiroUser();
            su.setTenentId(req.getTenantId());
            su.setCompanyCode(req.getOrgCode());

        } finally {
            Context.resetCurrentUser();
        }
        noticeWaitingTriggerListService.save(Sets.newHashSet(req.getUserIds()), req.getTitle(), req.getContent(), BusinessTypeEnum.valueOf(req.getBusinessType()).getBusinessCode(), req.getTaskCode(), new Date());
        // app通知中心
        ArrayList<CommonBusinessNotice> commonBusinessNotices = new ArrayList<>();
        for (Long userId : req.getUserIds()) {
            CommonBusinessNotice appNotify = new CommonBusinessNotice();
            appNotify.setBusinessType(AppBusinessNoticeTypes.valueOf(req.getAppBusinessType()).getType())
                    .setNoticeContent(String.format("[%s] %s", req.getTitle(), req.getContent()))
                    .setNoticeUser(userId)
                    .setNoticeTitle(req.getTitle())
                    .setSendTime(req.getSendTime())
                    .setRefId(req.getRefId());
            commonBusinessNotices.add(appNotify);
        }
        commonBusinessNoticeService.saveBatch(commonBusinessNotices);
        return ResultBean.defaultSuccessResult();
    }

    @GetMapping("/cascade/page")
    @ApiOperation("全部岗位信息分页接口")
    public ResultBean cascadePage(Integer page, Integer size, Long parentId, String label, Long tenantId, String orgCode) {
        LambdaQueryWrapper<CascadeConfig> query = new LambdaQueryWrapper<>();
        query.eq(CascadeConfig::getTenentId, tenantId);
        query.eq(CascadeConfig::getOrgCode, orgCode);
        query.eq(CascadeConfig::getParentId, parentId);
        if (!Strings.isNullOrEmpty(label)) {
            query.like(CascadeConfig::getLabel, label);
        }
        query.orderByAsc(CascadeConfig::getOrderVal);

        Page<CascadeConfig> pageForApi = new Page<>(page + 1, size);
        IPage<CascadeConfig> pageRes = cascadeConfigService.page(pageForApi, query);
        if (CollectionUtil.isNotEmpty(pageRes.getRecords())) {
            return ResultBean.pageData(pageRes.getRecords(), pageRes.getTotal());
        }
        return ResultBean.pageData(new ArrayList<>(), pageRes.getTotal());
    }
}
